/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Serwer;

import Helpers.Karty;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Vector;

/**
 *
 * @author cigol
 */
public class PokerSerwer {

    /**
     * @param args the command line arguments
     */
    private static final int BUFSIZE = 64;   // Size of receive buffer
    private int servPort = 1928;
    private ServerSocket servSock;
    /*--->*/ private Integer iloscGraczy;

    public PokerSerwer() throws IOException {
        this.servSock = new ServerSocket(this.servPort);
        this.iloscGraczy = 0;
    }

    public String odbierzDane(BufferedReader in) throws IOException {
        String dane = in.readLine();
        return dane;
    }

    public void wyslijDane(PrintWriter out, String dane) throws IOException {
        out.println(dane);
        out.flush();
    }

    // wysyla informacje do kazdego gracza
    public static void wyslijInfo(PokerSerwer serwer, Vector<Gracz> players, String wiadomosc) throws IOException {
        for (int i = 0; i < players.size(); ++i) {
            serwer.wyslijDane(players.get(i).getOut(), "info");
            serwer.wyslijDane(players.get(i).getOut(), wiadomosc);
        }
    }

    // wysyla infomrmacje , dane do kazdego gracza, nie komunikaty
    public static void wyslijStaty(PokerSerwer serwer, Vector<Gracz> players, Integer rodzaj, String wiadomosc) throws IOException {
        for (int i = 0; i < players.size(); ++i) {
            serwer.wyslijDane(players.get(i).getOut(), "staty");
            serwer.wyslijDane(players.get(i).getOut(), rodzaj.toString() + wiadomosc);
        }
    }
    //rodzaj - to rodzaj danych: ilosc graczy,

    // wysyla info do pojedynczego gracza
    public static void wyslijInfo(PokerSerwer serwer, Vector<Gracz> players, Integer numerGracza, String wiadomosc) throws IOException {
        serwer.wyslijDane(players.get(numerGracza).getOut(), "info");
        serwer.wyslijDane(players.get(numerGracza).getOut(), wiadomosc);
    }

    public static void wyslijNaglowek(PokerSerwer serwer, Vector<Gracz> players, String naglowek) throws IOException {
        // przesylamy info do klienta
        for (int i = 0; i < players.size(); ++i) {
            serwer.wyslijDane(players.get(i).getOut(), naglowek);
        }
    }

    public static void wyslijNaglowek(PokerSerwer serwer, Vector<Gracz> players, Integer numerGracza, String naglowek) throws IOException {
        // przesylamy info do klienta
        serwer.wyslijDane(players.get(numerGracza).getOut(), naglowek);
    }

    public static Integer odbierzInta(PokerSerwer serwer, Rozgrywka rozgrywka, Integer numerGracza, String naglowek) throws IOException {
        serwer.wyslijDane(rozgrywka.getGracz(numerGracza).getOut(), naglowek);
        String odebrane = serwer.odbierzDane(rozgrywka.getGracz(numerGracza).getIn());
        return new Integer(odebrane);
    }

    public static void main(String[] args) throws IOException {

        try {
            PokerSerwer serwer = new PokerSerwer();
            System.out.println("Serwer is started and is fine");
            //while (true) { // Run forever, accepting and servicing connections

            String odebrane;
            //Vector <Gracz> players = new Vector <Gracz>();

            Rozgrywka rozgrywka = new Rozgrywka();

            Socket clntSock = serwer.servSock.accept();


            rozgrywka.dodajGracza(clntSock);
            //players.add(new Gracz(clntSock));

            /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), 0, "Jestes 1. graczem, ustal ilosc graczy i poczatkowa kase.\n");

            // ilosc graczy w pokera
            serwer.iloscGraczy = odbierzInta(serwer, rozgrywka, 0, "iluGraczy");

            // pula wejsciowa
            Integer iloscKasy = odbierzInta(serwer, rozgrywka, 0, "iloscKasy");
            rozgrywka.setPulaWejsciowa(iloscKasy);

            /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), 0, "Gra dla " + serwer.iloscGraczy + " graczy.\n");
            /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), 0, "Poczatkowa kasa gracza = " + iloscKasy + "\n");

            // dodajemy n-1 nowych graczy
            for (int i = 1; i < serwer.iloscGraczy; ++i) {
                //wyslijInfo(serwer, rozgrywka.getGracze(), "Czekamy na kolejnych graczy");
 /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), "Czekamy na " + (i + 1) + ". gracza.\n");
                rozgrywka.dodajGracza(serwer.servSock.accept());

                /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), i, "Jestes " + (i + 1) + ". graczem. Ilosc graczy i " +
                        /*--->*/ "poczatkowa kasa juz zostala ustalona.\n");
                /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), i, "Gra dla " + serwer.iloscGraczy + " graczy.\n");
                /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), i, "Poczatkowa kasa gracza = " + iloscKasy + "\n");
                /*--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), "Gracz " + (i + 1) + ". juz jest podlaczony.\n");

            }
            System.out.println("Wszyscy zawodnicy dolaczyli do gry");
            /*--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 0, serwer.iloscGraczy.toString());


            // pytamy teraz kazdego gracza o login
            for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                serwer.wyslijDane(rozgrywka.getGracz(i).getOut(), "login");

                String login = serwer.odbierzDane(rozgrywka.getGracz(i).getIn());
                wyslijInfo(serwer, rozgrywka.getGracze(), "Do gry dolaczyl: " + login + "\n");
                /*--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 1, login);

                //wyslijInfo(serwer, players, "Do gry doszedl: "+login);
                rozgrywka.getGracz(i).setLogin(login);
            }


            wyslijInfo(serwer, rozgrywka.getGracze(), "Witamy w grze ;)\n");

            // przesylamy karty graczom
            for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                serwer.wyslijDane(rozgrywka.getGracz(i).getOut(), "wczytajKase");
                serwer.wyslijDane(rozgrywka.getGracz(i).getOut(), iloscKasy.toString());

                /*--->*/ String cokolwiek = serwer.odbierzDane(rozgrywka.getGracz(i).getIn());
            }

            /*--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 2, "budujemyStol");

            while (true) {

                wyslijNaglowek(serwer, rozgrywka.getGracze(), "nowaTura");
                rozgrywka.nowaTura();

                //wybieramy kolejnego gracza, od ktorego zaczyna sie kolejne rozdanie
                Integer diler = rozgrywka.getDiler();

                wyslijInfo(serwer, rozgrywka.getGracze(), "Tura numer: " + rozgrywka.getNumerTury() + "\n");

                /*NOWE--->*/ wyslijInfo(serwer, rozgrywka.getGracze(), "Zaczyna: " + (diler + 1) + ". gracz\n");

                // przesylamy karty graczom
                for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                    serwer.wyslijDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getOut(), "wysylanieKart");
                    serwer.wyslijDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getOut(), "5");
                    for (Integer j = 1; j <= 5; ++j) {
                        Integer karta = rozgrywka.wezKarte();
                        serwer.wyslijDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getOut(), karta.toString());
                    }
                }




                // wymieniamy karty, dostajemy od uzytkownika informacje ile tych kart
                // i pobieramy te karty
                Integer ileWymienic = null;
                for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                    String login = rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getLogin();
                    wyslijInfo(serwer, rozgrywka.getGracze(), "Uzytkownik (" + login + ") wymienia karty\n");
                    wyslijNaglowek(serwer, rozgrywka.getGracze(), (i + diler) % rozgrywka.iloscGraczy(), "ileWymienic");
                    odebrane = serwer.odbierzDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getIn());
                    ileWymienic = new Integer(odebrane);

                    for (int j = 1; j <= ileWymienic; ++j) {
                        odebrane = serwer.odbierzDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getIn());
                        rozgrywka.oddajKarte(new Integer(odebrane));
                    }
                    wyslijInfo(serwer, rozgrywka.getGracze(), "Uzytkownik (" + login + ") wymienil " + ileWymienic + " karty\n");

                    serwer.wyslijDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getOut(), "wysylanieKart");
                    serwer.wyslijDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getOut(), ileWymienic.toString());

                    for (int j = 1; j <= ileWymienic; ++j) {
                        Integer karta = rozgrywka.wezKarte();
                        //       System.out.println("karta: "+karta);
                        serwer.wyslijDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getOut(), karta.toString());
                    }
                }

                Integer stawka = 0;

                Integer licytujacy = rozgrywka.getLicytujacyGracz();


                while (true) {
                    if (rozgrywka.iloscLicytujacych() == 1) {
                        System.out.println("Zostal jeden gracz ktory zarazem wygral licytacje");
                        rozgrywka.setZwyciezca(licytujacy);
                        break;
                    }

                    stawka = odbierzInta(serwer, rozgrywka, licytujacy, "podajStawke");
                    System.out.println(rozgrywka.getGracz(licytujacy).getLogin() + " stawka: " + stawka);


                    int staraStawka = rozgrywka.getGracz(licytujacy).getStawka();
                    // licytacja trwa dopoki stawka jest taka sama jaka gracz wylozyl wczesniej
                    if (stawka == staraStawka) {
                        break;
                    }

                    if (stawka == -1) {
                        //rozgrywka.getGracz(licytujacy).setBierzeUdzial(false);

                        wyslijInfo(serwer, rozgrywka.getGracze(), "Uzytkownik (" + rozgrywka.getGracz(licytujacy).getLogin() + ") spasowal");

                        /*--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 4, licytujacy + "pas");

                        rozgrywka.usunLicytujacego(licytujacy);
                    } else {
                        wyslijNaglowek(serwer, rozgrywka.getGracze(), "aktualnaStawka");
                        wyslijNaglowek(serwer, rozgrywka.getGracze(), stawka.toString());

                        /*--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 3, licytujacy + "aktualnaMaxStawka");

                        wyslijInfo(serwer, rozgrywka.getGracze(), "Uzytkownik (" + rozgrywka.getGracz(licytujacy).getLogin() + ") zaaktualizowal stawke: " + stawka);
                        rozgrywka.getGracz(licytujacy).setPoprzedniaStawka(staraStawka);
                        rozgrywka.getGracz(licytujacy).setStawka(stawka);
                        rozgrywka.nastepnyLicytujacy();
                    }
                    wyslijInfo(serwer, rozgrywka.getGracze(), "Pula pieniedzy na stole wynosi: " + rozgrywka.ileNaStole());

                    /*--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 5, rozgrywka.ileNaStole().toString());

                    licytujacy = rozgrywka.getLicytujacyGracz();
                }
                wyslijNaglowek(serwer, rozgrywka.getGracze(), "koniecLicytacji");

                // przesylamy karty graczom

                /*NOWE--->*/ String wszystkieKartyGraczy = "";
                for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                    //serwer.wyslijDane(rozgrywka.getGracz(i).getOut(), "wysylanieKart");
                    //serwer.wyslijDane(rozgrywka.getGracz(i).getOut(), "5");
                    Integer hierarchia = odbierzInta(serwer, rozgrywka, (i + diler) % rozgrywka.iloscGraczy(), "podajHierarchie");
                    System.out.println("Hierarchie");
                    System.out.println((i + diler) % rozgrywka.iloscGraczy() + ": " + hierarchia);
                    wyslijInfo(serwer, rozgrywka.getGracze(), "Uzytkownik (" + rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getLogin() + ") miał w kartach: " + Karty.hierarchia(hierarchia));
                    rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).setHierachia(hierarchia);

                    /*NOWE--->*/ wszystkieKartyGraczy += "." + i + ".";
                    /*NOWE--->*/ wyslijNaglowek(serwer, rozgrywka.getGracze(), (i + diler) % rozgrywka.iloscGraczy(),
                            /*NOWE--->*/ "chceTwojeKarty");
                    /*NOWE--->*/ String jegoKarty = serwer.odbierzDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getIn());
                    /*NOWE--->*/ int k = 0;
                    /*NOWE--->*/ while (k < 10) {
                        /*NOWE--->*/ int wezKarte = (jegoKarty.charAt(k++) - 48) * 10;
                        /*NOWE--->*/ wezKarte += jegoKarty.charAt(k++) - 48;
                        /*NOWE--->*/ if (wezKarte < 10) {
                            /*NOWE--->*/ wszystkieKartyGraczy += "0" + wezKarte;
                        /*NOWE--->*/                        } else {
                            /*NOWE--->*/ wszystkieKartyGraczy += wezKarte;
                        /*NOWE--->*/                        }
                    /*NOWE--->*/                    }


                }
                /*NOWE--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 6, wszystkieKartyGraczy);

                Integer zwyciezca = rozgrywka.wybierzZwyciezce();

                wyslijInfo(serwer, rozgrywka.getGracze(), "Runde wygral gracz: " + rozgrywka.getGracz(zwyciezca).getLogin());
                wyslijNaglowek(serwer, rozgrywka.getGracze(), zwyciezca, "odbierzWygrana");
                wyslijNaglowek(serwer, rozgrywka.getGracze(), zwyciezca, rozgrywka.ileNaStole().toString());
                wyslijNaglowek(serwer, rozgrywka.getGracze(), "koniecTury");
                System.out.println("Koniec tury");
                /*NOWE--->*/ for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                    /*NOWE--->*/ String jegoKasa = serwer.odbierzDane(rozgrywka.getGracz((i + diler) % rozgrywka.iloscGraczy()).getIn());
                    /*NOWE--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 7,
                            ((i + diler) % rozgrywka.iloscGraczy()) + jegoKasa);
                /*NOWE--->*/                }

                /*NOWE--->*/ wyslijStaty(serwer, rozgrywka.getGracze(), 8, "noweRozdanie");
                /*NOWE--->*/ for (int i = 0; i < rozgrywka.iloscGraczy(); ++i) {
                    /*NOWE--->*/ String cos = serwer.odbierzDane(rozgrywka. /*NOWE--->*/getGracz((i + diler) % rozgrywka.iloscGraczy()).getIn());
                /*NOWE--->*/                }
            }
        } catch (SocketException e) {
        }
    }
}
